package net.studio.simpletetris;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;

import net.studio.simpletetris.control.AnimateThread;
import net.studio.simpletetris.control.Game;
import net.studio.simpletetris.intf.IField;
import net.studio.simpletetris.intf.IFigure;
import net.studio.simpletetris.intf.IGameListener;
import net.studio.simpletetris.intf.ISizeListener;
import net.studio.simpletetris.intf.IFigure.MoveDirect;
import net.studio.simpletetris.intf.IFigure.RotateDirect;
import net.studio.simpletetris.widget.GameView;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;

public class MainActivity extends BaseActivity implements OnLongClickListener, OnTouchListener, ISizeListener {
	public static final int WHAT_GAME_START      = 1;
	public static final int WHAT_GAME_STOP       = 2;
	public static final int WHAT_GAME_OVER       = 3;
	public static final int WHAT_GAME_SCORE      = 4;
	public static final int WHAT_GAME_NEW_FIGURE = 5;
	
	private Button btnStart;
	private Button btnPause;
	private Button btnReset;
	private ImageButton btnMoveDown;
	private ImageButton btnMoveLeft;
	private ImageButton btnMoveRight;
	private EditText edtLevel;
	private EditText edtScore;
	
	private GameView gameView;
	private GameView previewView;
	
	private boolean isRunning = false;
	private long score = 0;
	private int level = 1;
		
	private SoundPool soundPool;
	private int soundClick = 0;
	private int soundScore = 0;
	private int soundLevel = 0;
	private int soundGameOver = 0;
	private int streamClick = 0;
	
	private boolean isLongClick = false;
	
	private Handler handler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case WHAT_GAME_START:
				btnStart.setText(R.string.stop);
				btnPause.setText(R.string.pause);
				btnPause.setEnabled(true);
				btnReset.setEnabled(true);
				break;
			case WHAT_GAME_STOP:
				btnStart.setText(R.string.start);
				btnPause.setText(R.string.pause);
				btnPause.setEnabled(false);
				btnReset.setEnabled(false);
				break;
			case WHAT_GAME_OVER:
				btnStart.setText(R.string.start);
				btnPause.setText(R.string.pause);
				btnPause.setEnabled(false);
				btnReset.setEnabled(false);
				soundPool.play(soundGameOver, 1f, 1f, 1, 0, 1f);
				AnimateThread animateThread = new AnimateThread(gameView);
				animateThread.setRunning(true);
				animateThread.start();
//				AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
//				builder.setMessage(R.string.game_over)
//					.setTitle(R.string.app_name)
//					.setPositiveButton(android.R.string.ok, null);
//				AlertDialog dialog = builder.create();
//				dialog.show();
				break;
			case WHAT_GAME_SCORE:
				if (msg.arg1 > level) {
					soundPool.play(soundLevel, 1f, 1f, 1, 0, 1f);
				} else
					soundPool.play(soundScore, 1f, 1f, 1, 0, 1f);
				
				score = msg.arg1;
				level = msg.arg2;
				edtLevel.setText(String.valueOf(score));
				edtScore.setText(String.valueOf(level));
				break;
			}

		}
		
	};
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		getOverflowMenu();
		
		setVolumeControlStream(AudioManager.STREAM_MUSIC);
		
		soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);
		soundClick = soundPool.load(this, R.raw.choose, 1);
		soundScore = soundPool.load(this, R.raw.item2, 1);
		soundLevel = soundPool.load(this, R.raw.item1, 1);
		soundGameOver = soundPool.load(this, R.raw.lose, 1);
		
		btnStart = (Button)findViewById(R.id.btn_start);
		btnPause = (Button)findViewById(R.id.btn_pause);
		btnReset = (Button)findViewById(R.id.btn_reset);
		
		btnMoveDown = (ImageButton)findViewById(R.id.btn_move_down);
		btnMoveLeft = (ImageButton)findViewById(R.id.btn_move_left);
		btnMoveRight = (ImageButton)findViewById(R.id.btn_move_right);
		btnMoveDown.setOnLongClickListener(this);
		btnMoveLeft.setOnLongClickListener(this);
		btnMoveRight.setOnLongClickListener(this);
		btnMoveDown.setOnTouchListener(this);
		btnMoveLeft.setOnTouchListener(this);
		btnMoveRight.setOnTouchListener(this);
		
		edtLevel = (EditText)findViewById(R.id.edt_level);
		edtScore = (EditText)findViewById(R.id.edt_score);
		
		gameView = (GameView)findViewById(R.id.surfaceView1);
		previewView = (GameView)findViewById(R.id.surfaceView2);
		IField field = Game.newField(20, 10, 0xffcccccc);
		gameView.setField(field);
		field = Game.newField(4, 4, 0xffcccccc);
		previewView.setField(field);
		gameView.setSizeListener(this);
		previewView.setSizeListener(this);
		
		Game.factory(this, gameView, previewView, new IGameListener() {

			@Override
			public void onStart() {
				handler.obtainMessage(WHAT_GAME_START).sendToTarget();
			}

			@Override
			public void onStop() {
				handler.obtainMessage(WHAT_GAME_STOP).sendToTarget();
			}

			@Override
			public void onPause() {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onResume() {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onScore(int level, long score) {
				handler.obtainMessage(WHAT_GAME_SCORE, level, (int)score).sendToTarget();
			}

			@Override
			public void onNewFigure(IFigure figure) {
				handler.obtainMessage(WHAT_GAME_NEW_FIGURE, figure).sendToTarget();
			}

			@Override
			public void onGameOver() {
				handler.obtainMessage(WHAT_GAME_OVER).sendToTarget();
			}
			
		});
		
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		
		if (Game.instance != null) {
			Game.instance.stop();
		}
		
		gameView.setField(null);
		previewView.setField(null);
		
		if (soundClick != 0)
			soundPool.unload(soundClick);
		if (soundScore != 0)
			soundPool.unload(soundScore);
		if (soundLevel != 0)
			soundPool.unload(soundLevel);
		if (soundGameOver != 0)
			soundPool.unload(soundGameOver);
		soundPool.release();
		
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Intent intent;
		switch (item.getItemId()) {
		case R.id.action_share:
			doShareTo(this);
			break;
		case R.id.action_help:
			intent = new Intent(this, AboutActivity.class);
			startActivity(intent);
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void onPause() {
		super.onPause();
		
		if (Game.instance != null) {
			isRunning = Game.instance.isRunning();
			if (isRunning) {
				Game.instance.pause();
				isRunning = true;
			}
		}
	}

	@Override
	public void onResume() {
		super.onResume();
		
		if (Game.instance != null) {
			if (isRunning) {
				Game.instance.resume();
			}
		}
	}

	@Override
	protected int getContentView() {
		return R.layout.activity_main;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage(R.string.exit_app)
				.setTitle(R.string.app_name)
				.setNegativeButton(android.R.string.cancel, null)
				.setPositiveButton(android.R.string.ok,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int which) {
								dialog.dismiss();
								finish();
							}
						});
			AlertDialog dialog = builder.create();
			dialog.show();
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public boolean onLongClick(View v) {
		isLongClick = true;
		streamClick = soundPool.play(soundClick, 1f, 1f, 1, 1, 1f);
		switch (v.getId()) {
		case R.id.btn_move_down:
			if (Game.instance != null)
				Game.instance.moveExpress(MoveDirect.DOWN);
			break;
		case R.id.btn_move_left:
			if (Game.instance != null)
				Game.instance.moveExpress(MoveDirect.LEFT);
			break;
		case R.id.btn_move_right:
			if (Game.instance != null)
				Game.instance.moveExpress(MoveDirect.RIGHT);
			break;
		}
		return true;
	}
	
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		switch (v.getId()) {
		case R.id.btn_move_down:
		case R.id.btn_move_left:
		case R.id.btn_move_right:
			if (MotionEvent.ACTION_UP == event.getAction()) {
				if (streamClick != 0 && isLongClick) {
					soundPool.stop(streamClick);
					isLongClick = false;
				}
			}
		}
		return false;
	}

	@Override
	public void onSizeChanged(View view, int xNew, int yNew, int xOld, int yOld) {
		IField field = ((GameView)view).getField();
        if (field != null) {
        	int blockSize = xNew / field.getCols();
        	int rows = yNew / blockSize;
        	if (rows != field.getRows())
        		field.setRows(rows);
        	float frameX = (float)(xNew - blockSize * field.getCols()) / 2;
        	float frameY = (float)(yNew - blockSize * field.getRows()) / 2;
        	((GameView)view).setBlockSize(blockSize);
        	((GameView)view).setFrameX(frameX);
        	((GameView)view).setFrameY(frameY);
        }
        
	}
			
	public void onClick(View view) {
		switch (view.getId()) {
		case R.id.btn_start:
			if (Game.instance != null) {
				if (Game.instance.isRunning())
					Game.instance.stop();
				else
					Game.instance.play();
			}
			break;
		case R.id.btn_pause:
			if (Game.instance != null) {
				if (Game.instance.isRunning()) {
					Game.instance.pause();
					btnPause.setText(R.string.resume);
				} else {
					Game.instance.resume();
					btnPause.setText(R.string.pause);
				}
			}
			break;
		case R.id.btn_reset:
			if (Game.instance != null) {
				Game.instance.stop();
				Game.instance.play();
			}
			break;
		case R.id.btn_move_left:
			streamClick = soundPool.play(soundClick, 1f, 1f, 1, 0, 1f);
			if (Game.instance != null)
				Game.instance.move(MoveDirect.LEFT);
			break;
		case R.id.btn_move_right:
			streamClick = soundPool.play(soundClick, 1f, 1f, 1, 0, 1f);
			if (Game.instance != null)
				Game.instance.move(MoveDirect.RIGHT);
			break;
		case R.id.btn_move_down:
			streamClick = soundPool.play(soundClick, 1f, 1f, 1, 0, 1f);
			if (Game.instance != null)
				Game.instance.move(MoveDirect.DOWN);
			break;
		case R.id.btn_rotate:
			streamClick = soundPool.play(soundClick, 1f, 1f, 1, 0, 1f);
			if (Game.instance != null)
				Game.instance.rotate(RotateDirect.CLOCKWISE);
			break;
		}
	}

	private void getOverflowMenu() {
	    try {
	       ViewConfiguration config = ViewConfiguration.get(this);
	       Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
	       if(menuKeyField != null) {
	           menuKeyField.setAccessible(true);
	           menuKeyField.setBoolean(config, false);
	       }
	   } catch (Exception e) {
	       e.printStackTrace();
	   }
	}

	public static void doShareTo(Context context) {
    	InputStream is = context.getResources().openRawResource(R.raw.share_sms);
    	byte[] bytes;
		try {
			bytes = new byte[is.available()];
	        is.read(bytes);
	    	Intent intent=new Intent(Intent.ACTION_SEND);   
            intent.setType("text/plain");   
            intent.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.app_name));   
            intent.putExtra(Intent.EXTRA_TEXT, new String(bytes, "UTF-8"));   
            
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);   
            context.startActivity(Intent.createChooser(intent, context.getString(R.string.menu_shareto)));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
    
}
